#coding=utf-8
import datetime, decimal
import wx
import env, db
from utility import *
import wx.lib.pubsub as ps
import gui_campaign as gcamp

status_list = ['draft', 'active', 'paused']
class CampPanel(wx.Panel):
    def __init__(self, parent, id=-1):
        wx.Panel.__init__(self, parent, id)
        
        topLbl = wx.StaticText(self, -1, label="Campaign Information")
        topLbl.SetFont(wx.Font(11, wx.SWISS, wx.NORMAL, wx.BOLD))
        
        nameLbl = wx.StaticText(self, -1, "Name:")
        name = wx.TextCtrl(self, -1)
        self.name = name
        
        budgetLbl = wx.StaticText(self, -1, label="Budget:")
        budget = wx.TextCtrl(self, -1)
        h = budget.GetSize().height
        w = budget.GetSize().width + budget.GetPosition().x + 2
        budgetSpb = wx.SpinButton(self, -1,size=(h*2/3, h),style=wx.SP_VERTICAL)
        budgetSpb.SetRange(0, 500)
        budgetSpb.SetValue(0)
        self.budgetSpb = budgetSpb
        self.budget = budget
        self.Bind(wx.EVT_SPIN, self.OnSpin, budgetSpb)
        
        statusLbl = wx.StaticText(self, -1, label="Status:")
        status = wx.Choice(self, -1, choices = status_list)
        self.status = status
        
        startLbl = wx.StaticText(self, -1, label="Start On:")
        start = wx.TextCtrl(self, -1)
        endLbl = wx.StaticText(self, -1, label="End On:")
        end = wx.TextCtrl(self, -1)
        self.start = start
        self.end = end
        
        descLbl = wx.StaticText(self, -1, label="Description:")
        desc = wx.TextCtrl(self, -1,
                            style = wx.TE_MULTILINE|wx.TE_PROCESS_ENTER)
        self.desc = desc
        
        applyBtn = wx.Button(self, -1, "Apply")
        cancelBtn = wx.Button(self, -1, "Cancel")
        applyaddBtn = wx.Button(self, -1, "Apply and Add a New ad")
        self.Bind(wx.EVT_BUTTON, self.OnApply, applyBtn)
        self.Bind(wx.EVT_BUTTON, self.OnCancel, cancelBtn)
        
        """
        Layout
        """
        mainSizer = wx.BoxSizer(wx.VERTICAL)
        mainSizer.Add(topLbl, 0, wx.ALL, 5)
        mainSizer.Add(wx.StaticLine(self), 0,
                wx.EXPAND|wx.TOP|wx.BOTTOM, 5)
        
        infoSizer = wx.GridBagSizer(hgap=5, vgap=5)
        infoSizer.Add(nameLbl, pos=(0,0),flag=wx.ALIGN_RIGHT|wx.ALIGN_CENTER_VERTICAL)
        infoSizer.Add(name, pos=(0,1), span=(1, 3), flag=wx.EXPAND)
        
        infoSizer.Add(budgetLbl, pos=(1,0),flag=wx.ALIGN_RIGHT|wx.ALIGN_CENTER_VERTICAL)
        budgetSizer = wx.BoxSizer(wx.HORIZONTAL)
        budgetSizer.Add(budget, 1, flag=wx.EXPAND)
        budgetSizer.Add(budgetSpb)
        infoSizer.Add(budgetSizer, pos=(1,1), flag=wx.EXPAND)
        infoSizer.Add(statusLbl, pos=(1,2), flag=wx.ALIGN_RIGHT|wx.ALIGN_CENTER_VERTICAL)
        infoSizer.Add(status, pos=(1,3), flag=wx.EXPAND)
        
        infoSizer.Add(startLbl, pos=(2,0),flag=wx.ALIGN_RIGHT|wx.ALIGN_CENTER_VERTICAL)
        infoSizer.Add(start, pos=(2,1), flag=wx.EXPAND)
        infoSizer.Add(endLbl, pos=(2,2),flag=wx.ALIGN_RIGHT|wx.ALIGN_CENTER_VERTICAL)
        infoSizer.Add(end, pos=(2,3), flag=wx.EXPAND)
        
        infoSizer.Add(descLbl, pos=(3,0),flag=wx.ALIGN_RIGHT|wx.ALIGN_CENTER_VERTICAL)
        infoSizer.Add(desc, pos=(3,1), span=(4,3), flag=wx.EXPAND)
        
        infoSizer.AddGrowableCol(1)
        infoSizer.AddGrowableCol(3)
        mainSizer.Add(infoSizer, 0, wx.EXPAND|wx.ALL, 10)  
        
        mainSizer.Add(wx.StaticLine(self), 0,
                wx.EXPAND|wx.TOP|wx.BOTTOM, 5)
        btnSizer = wx.BoxSizer(wx.HORIZONTAL)
        btnSizer.Add((40,40), 1)
        btnSizer.Add(applyBtn)
        btnSizer.Add((10,10), 0)
        btnSizer.Add(applyaddBtn)
        btnSizer.Add((10,10), 0)
        btnSizer.Add(cancelBtn)
        btnSizer.Add((10,10), 0)
        
        mainSizer.Add(btnSizer, 0, wx.EXPAND|wx.BOTTOM, 10)
        
        self.SetSizer(mainSizer)
        mainSizer.Fit(self)
        mainSizer.SetSizeHints(self)
        
    def OnSpin(self, event):
        self.budget.SetValue(str(event.GetPosition()))
    
    def _Apply(self):
        
        self.camp.name = unicode(self.name.GetValue())
        
        self.camp.budget = decimal.Decimal( self.budget.GetValue())
        self.camp.status = unicode(status_list[self.status.GetCurrentSelection()])
        
        self.camp.start_on = str2date(self.start.GetValue())
        self.camp.end_on = str2date(self.end.GetValue())
        
        self.camp.description = unicode(self.desc.GetValue())
        self.camp.last_modified_at = datetime.datetime.now()
        
        env.current_user.campaigns.add(self.camp)
        env.store.add(self.camp)
        env.store.flush()
        
        ps.Publisher.sendMessage('Camp.ChangeApplied', self.camp)
        
    def OnApply(self, event):
        self._Apply()
    
    def OnCancel(self, envet):
        m = env.mainFrame

        m.mgr.GetPane("Camp").Hide()
        m.mgr.Update()
        
    def SetContent(self, camp):
        c = camp
        self.name.SetValue( c.name )
        
        self.budget.SetValue( str(c.budget) )
        self.budgetSpb.SetValue(c.budget)
        
        n = status_list.index(c.status)
        self.status.SetSelection(n)
        
        self.start.SetValue( c.start_on.isoformat() )
        self.end.SetValue( c.end_on.isoformat())
        
        self.desc.SetValue( c.description)
        
        self.camp = c
        
    def ClearContent(self):
        self.name.SetValue("")
        
        self.budget.SetValue(0)
        self.budgetSpb.SetValue(0)
        self.status.SetssSelection(0)
        
        self.start.SetValue(datetime.date.today().isoformat())
        self.end.SetValue(datetime.date.today().isoformat())
        
        self.desc.SetValue("")

class CampFrame(wx.Frame):
    def __init__(self, parent, id=-1, title="Add Campaign", pos=wx.DefaultPosition,
                 size=(550,290), style=wx.DEFAULT_FRAME_STYLE |
                                            wx.SUNKEN_BORDER |
                                            wx.CLIP_CHILDREN):
        
        wx.Frame.__init__(self, parent, id, title, pos, size, style)
        topLbl = wx.StaticText(self, -1, label="Add A New Campaign")
        topLbl.SetFont(wx.Font(11, wx.SWISS, wx.NORMAL, wx.BOLD))
        
        nameLbl = wx.StaticText(self, -1, "Name:")
        name = wx.TextCtrl(self, -1)
        self.name = name
        
        budgetLbl = wx.StaticText(self, -1, label="Budget:")
        budget = wx.TextCtrl(self, -1)
        h = budget.GetSize().height
        w = budget.GetSize().width + budget.GetPosition().x + 2
        budgetSpb = wx.SpinButton(self, -1,size=(h*2/3, h),style=wx.SP_VERTICAL)
        budgetSpb.SetRange(0, 500)
        budgetSpb.SetValue(0)
        self.budgetSpb = budgetSpb
        self.budget = budget
        self.Bind(wx.EVT_SPIN, self.OnSpin, budgetSpb)
        
        statusLbl = wx.StaticText(self, -1, label="Status:")
        status = wx.Choice(self, -1, choices = status_list)
        self.status = status
        
        startLbl = wx.StaticText(self, -1, label="Start On:")
        start = wx.TextCtrl(self, -1)
        endLbl = wx.StaticText(self, -1, label="End On:")
        end = wx.TextCtrl(self, -1)
        self.start = start
        self.end = end
        self.start.SetValue(datetime.date.today().isoformat())
        self.end.SetValue(datetime.date.today().isoformat())
        
        descLbl = wx.StaticText(self, -1, label="Description:")
        desc = wx.TextCtrl(self, -1,
                            style = wx.TE_MULTILINE|wx.TE_PROCESS_ENTER)
        self.desc = desc
        
        addBtn = wx.Button(self, -1, "Add")
        cancelBtn = wx.Button(self, -1, "Cancel")
        add2Btn = wx.Button(self, -1, "add and Add a New ad")
        self.Bind(wx.EVT_BUTTON, self.OnAdd, addBtn)
        self.Bind(wx.EVT_BUTTON, self.OnCancel, cancelBtn)
        self.Bind(wx.EVT_CLOSE, self.OnCancel)
        self.Centre()
        
        
        """
        Layout
        """
        mainSizer = wx.BoxSizer(wx.VERTICAL)
        mainSizer.Add(topLbl, 0, wx.ALL, 5)
        mainSizer.Add(wx.StaticLine(self), 0,
                wx.EXPAND|wx.TOP|wx.BOTTOM, 5)
        
        infoSizer = wx.GridBagSizer(hgap=5, vgap=5)
        infoSizer.Add(nameLbl, pos=(0,0),flag=wx.ALIGN_RIGHT|wx.ALIGN_CENTER_VERTICAL)
        infoSizer.Add(name, pos=(0,1), span=(1, 3), flag=wx.EXPAND)
        
        infoSizer.Add(budgetLbl, pos=(1,0),flag=wx.ALIGN_RIGHT|wx.ALIGN_CENTER_VERTICAL)
        budgetSizer = wx.BoxSizer(wx.HORIZONTAL)
        budgetSizer.Add(budget, 1, flag=wx.EXPAND)
        budgetSizer.Add(budgetSpb)
        infoSizer.Add(budgetSizer, pos=(1,1), flag=wx.EXPAND)
        infoSizer.Add(statusLbl, pos=(1,2), flag=wx.ALIGN_RIGHT|wx.ALIGN_CENTER_VERTICAL)
        infoSizer.Add(status, pos=(1,3), flag=wx.EXPAND)
        
        infoSizer.Add(startLbl, pos=(2,0),flag=wx.ALIGN_RIGHT|wx.ALIGN_CENTER_VERTICAL)
        infoSizer.Add(start, pos=(2,1), flag=wx.EXPAND)
        infoSizer.Add(endLbl, pos=(2,2),flag=wx.ALIGN_RIGHT|wx.ALIGN_CENTER_VERTICAL)
        infoSizer.Add(end, pos=(2,3), flag=wx.EXPAND)
        
        infoSizer.Add(descLbl, pos=(3,0),flag=wx.ALIGN_RIGHT|wx.ALIGN_CENTER_VERTICAL)
        infoSizer.Add(desc, pos=(3,1), span=(4,3), flag=wx.EXPAND)
        
        infoSizer.AddGrowableCol(1)
        infoSizer.AddGrowableCol(3)
        mainSizer.Add(infoSizer, 0, wx.EXPAND|wx.ALL, 10)  
        
        mainSizer.Add(wx.StaticLine(self), 0,
                wx.EXPAND|wx.TOP|wx.BOTTOM, 5)
        btnSizer = wx.BoxSizer(wx.HORIZONTAL)
        btnSizer.Add((40,40), 1)
        btnSizer.Add(addBtn)
        btnSizer.Add((10,10), 0)
        btnSizer.Add(add2Btn)
        btnSizer.Add((10,10), 0)
        btnSizer.Add(cancelBtn)
        btnSizer.Add((10,10), 0)
        
        mainSizer.Add(btnSizer, 0, wx.EXPAND|wx.BOTTOM, 10)
        
        self.SetSizer(mainSizer)
        mainSizer.Fit(self)
        mainSizer.SetSizeHints(self)
        
    def OnSpin(self, event):
        self.budget.SetValue(str(event.GetPosition()))
    
    def OnAdd(self, event): 
        camp = db.Campaign()
        
        camp.name = unicode(self.name.GetValue())
        
        camp.budget = decimal.Decimal( self.budget.GetValue())
        camp.status = unicode(status_list[self.status.GetCurrentSelection()])
        
        camp.start_on = str2date(self.start.GetValue())
        camp.end_on = str2date(self.end.GetValue())
        
        camp.description = unicode(self.desc.GetValue())
        camp.last_modified_at = datetime.datetime.now()
        
        env.current_user.campaigns.add(camp)
        env.store.add(camp)
        env.store.flush()
        
        ps.Publisher.sendMessage('Camp.Added', camp)
        
        self.Hide()
        self.Parent.Enable(True)
        
    def OnCancel(self, evnet):
        self.Hide()
        self.Parent.Enable(True)
        
if __name__ == '__main__':
    app = wx.PySimpleApp()
    frame = wx.Frame(None, size=(550,290))
    CampPanel(parent=frame)
    frame.Show()
    app.MainLoop()
